/**********************************************************
 * File description:ConfigFileService.cpp
 * Function:配置文件服务类
 * Current Version: 1.0.0
 * Author: 夏新宇
 * Date: 2022-11-16
 *  -----
 *  Copyright by bokun Software.
 **********************************************************/

#include "ConfigFileService.h"


/*!
 * \brief 构造函数
 *
 * \param
 *
 *
 * \return
 *
 * Detail here!!!
 */
ConfigFileService::ConfigFileService()
{
    path = QCoreApplication::applicationDirPath();
    conv = new Convertion();
    char * filePath;
    QByteArray tempByte = (path + "/" + CONFIG_FILE_NAME).toLocal8Bit();
    filePath = tempByte.data();
    simplexml = new Simplexml(filePath);
}
/*!
 * \brief 获取所有实验类型
 *
 * \param
 * \param QList<QString> 包含所有实验类型的数组
 *
 *
 * \return
 *
 * Detail here!!!
 */

QList<QString> ConfigFileService::getExperimentType(){

    QList<QString> res;
    try{
        simplexml->next("experiments");
        QString num = simplexml->child("type-num")->text();
        for(int i = 0;i < num.toInt();i ++){
            res.append(simplexml->child("experiment",i)->child("type")->text());
        }
        simplexml->previous();
    }catch(...){
        qDebug() << "配置文件信息读取异常" << endl;
    }
    return res;
}

/*!
 * \brief 获取所有耗材类型
 *
 * \param
 * \param QList<QString> 包含所有耗材类型的数组
 *
 *
 * \return
 *
 * Detail here!!!
 */
QList<QString> ConfigFileService::getConsumablesType(){
    QList<QString> res;
    try{
        simplexml->next("reaction-plate")->next("consumables");
        QString num = simplexml->child("num")->text();
        for(int i = 0;i < num.toInt();i ++){
            res.append(simplexml->child("consumable",i)->child("name")->text());
        }
        simplexml->previous();
        simplexml->previous();
    }catch(...){
        qDebug() << "配置文件信息读取异常" << endl;
    }
    return res;
}

/*!
 * \brief 根据耗材类型获取反应板行数
 *
 * \param
 * \param int[] 长度为2的数组，第一个元素为反应板行数，第二个元素为反应板列数
 *
 *
 * \return
 *
 * Detail here!!!
 */
int* ConfigFileService::getRowAndColByConsumableType(QString consumableType){
    int * res = (int*)malloc(sizeof(int)*2);
    try{
        simplexml->next("reaction-plate")->next("consumables");
        QString num = simplexml->child("num")->text();
        for(int i = 0;i < num.toInt();i ++){
            if(simplexml->child("consumable",i)->child("name")->text() == consumableType){
                res[0] = QString(simplexml->child("consumable",i)->child("rows")->text()).toInt();
                res[1] = QString(simplexml->child("consumable",i)->child("cols")->text()).toInt();
                break;
            }
        }
        simplexml->previous();
        simplexml->previous();
    }catch(...){
        qDebug() << "配置文件信息读取异常" << endl;
    }
    return res;
}

/*!
 * \brief 获取所有靶基因类型
 *
 * \param
 * \param QList<QString> 包含所有靶基因类型的数组
 *
 *
 * \return
 *
 * Detail here!!!
 */
QList<QString> ConfigFileService::getTargetType(){
    QList<QString> res;
    try{
        simplexml->next("reaction-plate")->next("target");
        QString num = simplexml->child("types")->child("num")->text();
        for(int i = 0;i < num.toInt();i ++){
            res.append(simplexml->child("types")->child("type",i)->text());
        }
        simplexml->previous();
        simplexml->previous();
    }catch(...){
        qDebug() << "配置文件信息读取异常" << endl;
    }
    return res;
}

/*!
 * \brief 获取所有染料信息
 *
 * \param
 * \param QList<QHash<QString,QString>> 包含所有染料的数组
 *
 *
 * \return
 *
 * Detail here!!!
 */
QList<QHash<QString,QString>> ConfigFileService::getDyes(){
    QList<QHash<QString,QString>> res;
    try{
        simplexml->next("reaction-plate")->next("target")->next("dyes");
        QString num = simplexml->child("num")->text();
        for(int i = 0;i < num.toInt();i ++){
            QHash<QString,QString> dye;
            dye["name"] = simplexml->child("dye",i)->child("name")->text();
            dye["creator"] = simplexml->child("dye",i)->child("creator")->text();
            dye["type"] = simplexml->child("dye",i)->child("type")->text();
            dye["wavelength"] = simplexml->child("dye",i)->child("wavelength")->text();
            res.append(dye);
        }
        simplexml->previous();
        simplexml->previous();
        simplexml->previous();
    }catch(...){
        qDebug() << "配置文件信息读取异常" << endl;
    }
    return res;
}

/*!
 * \brief 获取进入维护界面的密码
 *
 * \param
 * \param QString 进入维护界面的密码
 *
 *
 * \return
 *
 * Detail here!!!
 */
QString ConfigFileService::getWeihuPassword(){
    QString res;
    try{
        res = simplexml->next("maintain")->next("password")->text();
        simplexml->previous();
        simplexml->previous();
    }catch(...){
        qDebug() << "配置文件信息读取异常" << endl;
    }
    return res;
}

/*!
 * \brief 根据实验类型获取对应的阶段名称
 *
 * \param
 * \param QList<QString> 包括制定实验类型下的所有阶段名称
 *
 *
 * \return
 *
 * Detail here!!!
 */
QList<QString> ConfigFileService::getStageNameByExperimentType(QString experimentType){
    QList<QString> res;
    try{
        QString num = simplexml->next("experiments")->child("type-num")->text();
        for(int i = 0;i < num.toInt();i ++){
            if(QString(simplexml->child("experiment",i)->child("type")->text()) == experimentType){
                QString stageNum = simplexml->next("experiment",i)->next("stages")->child("stage-num")->text();
                for(int j = 0;j < stageNum.toInt();j ++){
                    res.append(simplexml->child("stage",j)->child("name")->text());
                }
                simplexml->previous();
                simplexml->previous();
                break;
            }
        }
        simplexml->previous();
    }catch(...){
        qDebug() << "配置文件信息读取异常" << endl;
    }
    return res;
}

/*!
 * \brief 根据阶段名称获取对应的阶段
 *
 * \param
 * \param ProcedureStep 包括阶段信息的结构体
 *
 *
 * \return
 *
 * Detail here!!!
 */
ProcedureStage ConfigFileService::getStageByStageName(QString stageName){
    ProcedureStage res;
    try{
        QString num = simplexml->next("procedure")->child("stage-num")->text();
        for(int i = 0;i < num.toInt();i ++){
            if(QString(simplexml->child("stage",i)->child("name")->text()) == stageName){
                res.name = simplexml->child("stage",i)->child("name")->text();
                res.cycle_number = simplexml->child("stage",i)->child("cycle-number")->text();
                break;
            }
        }
        simplexml->previous();
    }catch(...){
        qDebug() << "配置文件信息读取异常" << endl;
    }
    return res;
}


/*!
 * \brief 根据阶段名称获取对应的步骤
 *
 * \param
 * \param ProcedureStep 包括阶段信息的结构体
 *
 *
 * \return
 *
 * Detail here!!!
 */
QList<ProcedureStep> ConfigFileService::getStepByStageName(QString stageName){


    QList<ProcedureStep> res;
    try{
        QString num = simplexml->next("procedure")->child("stage-num")->text();
        for(int i = 0;i < num.toInt();i ++){
            if(QString(simplexml->child("stage",i)->child("name")->text()) == stageName){
                QString stepNum = simplexml->next("stage",i)->child("step-num")->text();
                for(int j = 0;j < stepNum.toInt();j ++){
                    ProcedureStep step;
                    step.temperature = simplexml->child("step",j)->child("temperature")->text();
                    step.duration = simplexml->child("step",j)->child("duration")->text();
                    step.rate = simplexml->child("step",j)->child("rate")->text();
                    step.is_fluorescence = simplexml->child("step",j)->child("is-fluorescence")->text();
                    res.append(step);
                }
                simplexml->previous();
                break;
            }

        }
        simplexml->previous();
    }catch(string s){
        std::cout << s << endl;
        qDebug() << "配置文件信息读取异常" << endl;
    }
    return res;
}

/*!
 * \brief 获取命令字信息及故障信息
 *
 * \param
 * \param QHash<QString,QString> key——命令字，value——故障信息
 *
 *
 * \return
 *
 * Detail here!!!
 */
QHash<QString,QString> ConfigFileService::getCommandAndFault(){

    QHash<QString,QString> res;
    try{
        QString num = simplexml->next("faults")->child("num")->text();
        for(int i = 0;i < num.toInt();i ++){
            res[simplexml->child("fault",i)->child("command")->text()] = simplexml->child("fault",i)->child("message")->text();
        }
        simplexml->previous();
    }catch(string s){
        std::cout << s << endl;
        qDebug() << "配置文件信息读取异常" << endl;
    }
    return res;
}


/*!
 * \brief 获取命令字信息及故障信息
 *
 *
 * \param QString 软件信息
 *
 *
 * \return
 *
 * Detail here!!!
 */
QString ConfigFileService::getSoftwareInfo(){
    QString res;
    try{
        res = simplexml->next("software-info")->text();
        simplexml->previous();
    }catch(string s){
        std::cout << s << endl;
        qDebug() << "配置文件信息读取异常" << endl;
    }
    return res;
}
